package net.lab1024.sa.admin.module.business.aps.domain.optaplanner;

import lombok.Data;
import lombok.NoArgsConstructor;
import org.optaplanner.core.api.domain.entity.PlanningEntity;
import org.optaplanner.core.api.domain.variable.PlanningVariable;

import java.time.LocalDateTime;

/**
 * OptaPlanner任务实体
 * 用于APS排程优化的规划实体
 *
 * @Author 1024创新实验室
 * @Date 2025-01-28
 * @Wechat zhuoda1024
 * @Email lab1024@163.com
 * @Copyright <a href="https://1024lab.net">1024创新实验室</a>
 */
@Data
@NoArgsConstructor
@PlanningEntity
public class Task {

    /**
     * 任务ID
     */
    private Long taskId;

    /**
     * 任务名称
     */
    private String taskName;

    /**
     * 任务描述
     */
    private String description;

    /**
     * 任务持续时间（分钟）
     */
    private Integer duration;

    /**
     * 优先级 (1-10，数字越大优先级越高)
     */
    private Integer priority;

    /**
     * 最早开始时间
     */
    private LocalDateTime earliestStartTime;

    /**
     * 最晚结束时间
     */
    private LocalDateTime latestEndTime;

    /**
     * 所需资源类型
     */
    private String requiredResourceType;

    /**
     * 前置任务ID列表（逗号分隔）
     */
    private String predecessorTaskIds;

    /**
     * 规划变量：分配的资源
     */
    @PlanningVariable(valueRangeProviderRefs = "resourceRange")
    private Resource assignedResource;

    /**
     * 规划变量：开始时间
     */
    @PlanningVariable(valueRangeProviderRefs = "timeSlotRange")
    private TimeSlot startTimeSlot;

    /**
     * 构造函数
     */
    public Task(Long taskId, String taskName, String description, Integer duration, 
                Integer priority, LocalDateTime earliestStartTime, LocalDateTime latestEndTime,
                String requiredResourceType, String predecessorTaskIds) {
        this.taskId = taskId;
        this.taskName = taskName;
        this.description = description;
        this.duration = duration;
        this.priority = priority;
        this.earliestStartTime = earliestStartTime;
        this.latestEndTime = latestEndTime;
        this.requiredResourceType = requiredResourceType;
        this.predecessorTaskIds = predecessorTaskIds;
    }

    /**
     * 获取任务结束时间
     */
    public LocalDateTime getEndTime() {
        if (startTimeSlot == null) {
            return null;
        }
        return startTimeSlot.getStartTime().plusMinutes(duration);
    }

    /**
     * 检查是否违反时间约束
     */
    public boolean isTimeConstraintViolated() {
        if (startTimeSlot == null) {
            return false;
        }
        
        LocalDateTime startTime = startTimeSlot.getStartTime();
        LocalDateTime endTime = getEndTime();
        
        // 检查是否在允许的时间范围内
        return startTime.isBefore(earliestStartTime) || endTime.isAfter(latestEndTime);
    }

    /**
     * 检查资源类型是否匹配
     */
    public boolean isResourceTypeMatched() {
        if (assignedResource == null || requiredResourceType == null) {
            return false;
        }
        return requiredResourceType.equals(assignedResource.getResourceType());
    }
}